package com.example.bpmervice.config;

import com.alibaba.druid.pool.DruidDataSource;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.impl.history.HistoryLevel;
import org.flowable.engine.*;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.io.IOException;

@Configuration
@Slf4j
public class FlowableConfig {

    @Value("${spring.datasource.dynamic.datasource.mysql.url}")
    private String jdbcUrl;

    @Value("${spring.datasource.dynamic.datasource.mysql.username}")
    private String username;

    @Value("${spring.datasource.dynamic.datasource.mysql.password}")
    private String password;

    @Value("${spring.datasource.dynamic.datasource.mysql.driver-class-name}")
    private String driverClassName;


    @Bean("flowableDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.mysql")
    public DataSource flowableDataSource() {
        // 手动创建 Druid 数据源并确保属性被正确绑定
        DruidDataSource dataSource = new DruidDataSource();

        // 这里需要确保 application.yml 中的配置正确
        // 或者使用 DataSourceBuilder 但明确设置类型
        return DataSourceBuilder.create()
                .type(DruidDataSource.class)
                .build();
    }

    /**
     * Flowable 事务管理器
     */
    @Bean("flowableTransactionManager")
    public PlatformTransactionManager flowableTransactionManager(
            @Qualifier("flowableDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    /**
     * Flowable 进程引擎配置
     */
    @Bean
    public SpringProcessEngineConfiguration processEngineConfiguration(
            @Qualifier("flowableDataSource") DataSource dataSource,
            @Qualifier("flowableTransactionManager") PlatformTransactionManager transactionManager) {

        SpringProcessEngineConfiguration config = new SpringProcessEngineConfiguration();
        config.setDataSource(dataSource);
        config.setTransactionManager(transactionManager);

        // 关键配置：自动创建表
        config.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);

        config.setAsyncExecutorActivate(false);
        config.setHistoryLevel(HistoryLevel.FULL);

        // 明确设置数据库类型
        config.setJdbcUrl(jdbcUrl);
        config.setJdbcUsername(username);
        config.setJdbcPassword(password);
        config.setJdbcDriver(driverClassName);

        // 设置数据库架构更新
//        config.setDbHistoryUsed( true);
//        config.setDatabaseTablePrefix("act_");

        // 设置数据库类型（可选，Flowable会自动检测）
        // config.setDatabaseType("mysql");

        /**
         * 部署模式说明：
         * - default: 默认模式，每个bpmn文件作为一个独立的部署
         * - single-resource: 将所有bpmn文件合并为一个部署
         * - resource-parent-folder: 根据父文件夹分组部署
         */
        // 启用自动部署
        config.setDeploymentMode("default");

        // 设置流程定义文件路径
        try {
            Resource[] resources = new PathMatchingResourcePatternResolver()
                    .getResources("classpath*:/processes/*.bpmn20.xml");
            config.setDeploymentResources(resources);
            log.info("找到 {} 个流程定义文件", resources.length);
        } catch (IOException e) {
            log.warn("未找到流程定义文件", e);
        }

        log.info("Flowable 进程引擎配置完成");
        return config;
    }

    /**
     * Flowable 进程引擎
     */
    @Bean
    public ProcessEngine processEngine(SpringProcessEngineConfiguration configuration) {
        ProcessEngine processEngine = configuration.buildProcessEngine();
        log.info("Flowable 进程引擎启动成功，版本: {}", processEngine.VERSION);
        return processEngine;
    }

    /**
     * Flowable 服务 Bean
     */
    @Bean
    public RepositoryService repositoryService(ProcessEngine processEngine) {
        return processEngine.getRepositoryService();
    }

    @Bean
    public RuntimeService runtimeService(ProcessEngine processEngine) {
        return processEngine.getRuntimeService();
    }

    @Bean
    public TaskService taskService(ProcessEngine processEngine) {
        return processEngine.getTaskService();
    }

    @Bean
    public HistoryService historyService(ProcessEngine processEngine) {
        return processEngine.getHistoryService();
    }

    @Bean
    public ManagementService managementService(ProcessEngine processEngine) {
        return processEngine.getManagementService();
    }
}
